﻿#if !LITE
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Reflection;
using System.Drawing.Imaging;

using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.codec;


namespace iPdf
{
    class PdfToXConverter : Actor<DestinationItem, PdfToXOption>
    {

        private static Dictionary<PdfCreatorFormat, ImageFormat> imageFormatDict = new Dictionary<PdfCreatorFormat, ImageFormat>();

        static PdfToXConverter()
        {
            imageFormatDict.Add(PdfCreatorFormat.BMP, ImageFormat.Bmp);
            imageFormatDict.Add(PdfCreatorFormat.EMF, ImageFormat.Emf);
            imageFormatDict.Add(PdfCreatorFormat.EXIF, ImageFormat.Exif);
            imageFormatDict.Add(PdfCreatorFormat.GIF, ImageFormat.Gif);
            imageFormatDict.Add(PdfCreatorFormat.ICO, ImageFormat.Icon);
            imageFormatDict.Add(PdfCreatorFormat.JPEG, ImageFormat.Jpeg);
            imageFormatDict.Add(PdfCreatorFormat.PNG, ImageFormat.Png);
            imageFormatDict.Add(PdfCreatorFormat.TIFF, ImageFormat.Tiff);
            imageFormatDict.Add(PdfCreatorFormat.WMF, ImageFormat.Wmf);
        }

        protected override void Work()
        {
            Helper.VerifyItem(workItem.Source, workItem.Destination);
            string src = workItem.Source;
            string dest = workItem.Destination;

            Assembly assembly = Assembly.LoadFrom(Global.PdfConverterPath);

            string convertMethodName = "ConvertByFormat";
            string tempFileName;

            PdfCreatorFormat format;
            if (pageOption.Format == PdfCreatorFormat.PDF ||
                pageOption.Format == PdfCreatorFormat.PDF_A ||
                pageOption.Format == PdfCreatorFormat.PDF_X)
            {
                format = pageOption.Format;
                tempFileName = Helper.GetTemporaryFile(Global.PdfExt);
            }
            else
            {
                format = PdfCreatorFormat.TIFF;
                tempFileName = Helper.GetTemporaryFile(Global.TiffExt);
            }

            foreach (Type type in assembly.GetTypes())
            {
                MethodInfo convertMethod = type.GetMethod(convertMethodName);
                if (convertMethod != null)
                {
                    object instance = Activator.CreateInstance(type);
                    try
                    {
                        convertMethod.Invoke(instance, new object[] 
                        { 
                            PdfCreator.GhostScriptLibDirectory, Helper.SystemFontsDir,
                            src, tempFileName, pageOption.XResolution, 
                            pageOption.YResolution, (int)format 
                        }
                        );
                    }
                    catch (Exception ex)
                    {
                        throw ex.InnerException;
                    }
                    break;
                }
            }

            if (!File.Exists(tempFileName))
            {
                throw new ConversionFailed(workItem.Source, workItem.Destination);
            }

            switch (pageOption.Format)
            {
                case PdfCreatorFormat.TIFF:
                    Helper.CopyFile(tempFileName, dest);
                    break;

                case PdfCreatorFormat.PDF:
                case PdfCreatorFormat.PDF_A:
                case PdfCreatorFormat.PDF_X:
                    PdfReader srcPdf = new PdfReader(src);

                    PdfStamper stamper = null;
                    PdfReader tempPdf = new PdfReader(tempFileName);

                    stamper = new PdfStamper(tempPdf, Helper.OpenWrite(dest));

                    PdfWriter writer = stamper.Writer;
                    if (pageOption.Format == PdfCreatorFormat.PDF_A)
                    {
                        writer.PDFXConformance = PdfWriter.PDFA1B;
                        writer.CreateXmpMetadata();
                    }

                    stamper.Close();
                    tempPdf.Close();
                    srcPdf.Close();
                    break;

                default:
                    System.Drawing.Image tiffImg = System.Drawing.Image.FromFile(tempFileName);
                    int numOfPages = TiffImageSplitter.GetPageCount(tiffImg);
                    if (numOfPages == 1)//only one page
                    {
                        SaveIthTiffImage(tiffImg, 1, dest, pageOption.Format);
                        break;
                    }

                    string pageSuffix = ".Page";
                    int lastDotIndex = dest.LastIndexOf(Helper.Dot);
                    for (int i = 0; i < numOfPages; ++i)
                    {
                        string suffix = pageSuffix + (i + 1);
                        string fileName = dest.Insert(lastDotIndex, suffix);
                        SaveIthTiffImage(tiffImg, i, fileName, pageOption.Format);
                    }

                    break;
            }
        }

        private void SaveIthTiffImage(System.Drawing.Image tiffImg, int i, string fileName, PdfCreatorFormat format)
        {
            System.Drawing.Image img = TiffImageSplitter.GetTiffImage(tiffImg, i);
            Helper.DeleteFile(fileName);
            img.Save(fileName, imageFormatDict[format]);
        }
    }
}

#endif